package com.starmark.sys.org.atomic.service.impl;


import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.Cached;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.starmark.core.framework.base.AbstractBaseService;
import com.starmark.core.framework.util.BeanMapper;
import com.starmark.sys.org.api.dto.OrgDepartmentInfoDto;
import com.starmark.sys.org.api.dto.OrgElementDto;
import com.starmark.sys.org.api.service.IOrgDepartmentApiService;
import com.starmark.sys.org.atomic.constants.SysOrgConstant;
import com.starmark.sys.org.atomic.entity.SysOrgDept;
import com.starmark.sys.org.atomic.mapper.SysOrgDeptMapper;
import com.starmark.sys.org.atomic.service.ISysOrgDeptService;
import com.starmark.sys.org.atomic.vo.SysOrgDeptVo;
import cn.hutool.core.util.StrUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author starmark
 * @version 2018年5月20日 下午3:19:19
 */
@Service("sysOrgDeptService")
public class SysOrgDeptServiceImpl extends AbstractBaseService<SysOrgDeptMapper, SysOrgDept>
        implements ISysOrgDeptService, IOrgDepartmentApiService {


    @Override
    public void buildPageSearch(Map<String, Object> params, QueryWrapper<SysOrgDept> eWrapper) {
        if (params.get("keyword") != null && StrUtil.isNotEmpty(params.get("keyword") + "")) {
            eWrapper.like("name", params.get("keyword") + "");
        }
        if (params.get("parentId") != null && StrUtil.isNotEmpty(params.get("parentId").toString())) {
            eWrapper.eq("parent_id", params.get("parentId"));
        } else {
            eWrapper.isNull("parent_id");
        }

    }


    @Override
    public List<OrgElementDto> getOrgTreeBySearchkey(String searchKey, int pageSize) {
        return this.baseMapper.getOrgTreeBySearchkey(searchKey, pageSize);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveDept(SysOrgDeptVo sysOrgDeptVo) {
        SysOrgDept sysOrgDept = BeanMapper.map(sysOrgDeptVo, SysOrgDept.class);
        sysOrgDept.setId(IdWorker.getIdStr());
        if (StrUtil.isNotEmpty(sysOrgDept.getParentId())) {
            SysOrgDept parentDept = this.getById(sysOrgDept.getParentId());
            sysOrgDept.setLevelId(parentDept.getLevelId() + sysOrgDept.getId() + SysOrgConstant.ORG_LEVEL_ID_SPLIT);
        } else {
            sysOrgDept.setLevelId(SysOrgConstant.ORG_LEVEL_ID_SPLIT + sysOrgDept.getId() + SysOrgConstant.ORG_LEVEL_ID_SPLIT);
        }
        this.save(sysOrgDept);
        return sysOrgDept.getId();
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public String updateDept(SysOrgDeptVo sysOrgDeptVo) {
        SysOrgDept sysOrgDept = BeanMapper.map(sysOrgDeptVo, SysOrgDept.class);
        if (StrUtil.isNotEmpty(sysOrgDept.getParentId())) {
            SysOrgDept parentDept = this.getById(sysOrgDept.getParentId());
            sysOrgDept.setLevelId(parentDept.getLevelId() + sysOrgDept.getId() + SysOrgConstant.ORG_LEVEL_ID_SPLIT);
        } else {
            sysOrgDept.setLevelId(SysOrgConstant.ORG_LEVEL_ID_SPLIT + sysOrgDept.getId() + SysOrgConstant.ORG_LEVEL_ID_SPLIT);
        }
        this.updateById(sysOrgDept);
        //更新子部门下的全部数据
        SysOrgDept oldSysOrgDept = this.getById(sysOrgDept.getId());
        if (!Objects.equals(oldSysOrgDept.getParentId(), sysOrgDept.getParentId())) {
            this.updateChildDeptLevel(oldSysOrgDept.getLevelId(), sysOrgDept.getLevelId(), Instant.now().toEpochMilli(), sysOrgDept.getUpdateBy());
        }


        return sysOrgDept.getId();
    }

    @Override
    public List<OrgElementDto> getOrgTreeById(String id) {

        return this.baseMapper.getOrgTreeById(id);
    }

    @Override
    public Map<String, String> findDeptMapByIds(List<String> ids) {
        Collection<SysOrgDept> depts = this.listByIds(ids);
        return depts.stream().collect(Collectors.toMap(SysOrgDept::getId, SysOrgDept::getName));
    }

    @Override
    public void updateChildDeptLevel(String oldLevelId, String newLevelId, long updateTime, String updateBy) {
        if (Objects.equals(oldLevelId, newLevelId)) {
            return;

        }
        this.baseMapper.updateChildDeptLevel(oldLevelId, newLevelId, updateTime, updateBy);
    }

    @Override
    public List<OrgDepartmentInfoDto> findDepartListByIds(List<String> ids) {
        Collection<SysOrgDept> depts = this.listByIds(ids);
        return BeanMapper.mapList(depts, OrgDepartmentInfoDto.class);
    }

    @Override
    @Cached(name = "sysOrgDeptService:findDepartInfoById:", key = "#id", cacheType = CacheType.BOTH)
    public OrgDepartmentInfoDto findDepartInfoById(String id) {
        SysOrgDept orgDept = this.getById(id);
        return BeanMapper.map(orgDept, OrgDepartmentInfoDto.class);
    }

}
